#include "palrender.h"
#include <gtkmm.h>

Color& Palette_Renderer::prepare(int id, Cairo::RefPtr<Cairo::Context>& context )
{
	Color& col = (*this)()[id];
	context->set_source_rgb(cairo_color(col.Red()),cairo_color(col.Green()),cairo_color(col.Blue()));
	return col;
}
bool Palette_Renderer::on_draw(GdkEventExpose *event)
{
	Cairo::RefPtr<Cairo::Context> context = ( get_window()->create_cairo_context() );
	Gtk::Allocation allocation = get_allocation();
	const int width = allocation.get_width();
	const int height = allocation.get_height();
	const int paddingW=2,paddingH=2;
	const int colW = (width) / 4;//4 = padding.
	const int colH = (height) / 4;
	try
	{
		Palette& l_pal = (*this)();
		for(unsigned int y=0,color=0;y<4;y++)
			for( unsigned int x=0;x<4;x++,color++)
			{
				prepare((y*4)+x,context);
				context->rectangle(x*colW+paddingW,y*colH+paddingH,colW-2*paddingW,colH-2*paddingH);
				context->fill();
			}
		
	}
	catch( Reference<Palette>::NullReference )
	{
		context->set_source_rgba(0,0,0,.6);
		context->rectangle(0,0,width,height);
		context->fill();
	}
	return true;
}
bool Palette_Renderer::on_click(GdkEventButton *event)
{
	try
	{
		Palette& l_pal = (*this)();
		Gtk::ColorSelection &CS = *mCSD.get_color_selection();
		Gtk::Allocation allocation = get_allocation();
		const int width = allocation.get_width();
		const int height = allocation.get_height();
		const int colW = (width) / 4;//4 = padding.
		const int colH = (height) / 4;
		Color& mc = l_pal[static_cast<unsigned int>(floor(event->y/colH)) * 4 + static_cast<unsigned int>(floor(event->x/colW))];
		Gdk::Color l_gdkcolor;
		l_gdkcolor.set_red(mc.Red()<<8);
		l_gdkcolor.set_green(mc.Green()<<8);
		l_gdkcolor.set_blue(mc.Blue()<<8);
		CS.set_current_color(l_gdkcolor);
		int response = mCSD.run();
		if( response == Gtk::RESPONSE_OK || response == Gtk::RESPONSE_ACCEPT ) {
			l_gdkcolor = CS.get_current_color();
			mc.Red( l_gdkcolor.get_red() >> 8 );
			mc.Green( l_gdkcolor.get_green() >> 8 );
			mc.Blue( l_gdkcolor.get_blue() >> 8 );
			mCSD.hide();
			on_draw(NULL);
		} else 	mCSD.hide();
	
	}
	catch( Reference<Palette>::NullReference ) {}
	return true;
}
Palette_Renderer::Palette_Renderer():mCSD("Choose a new color.")
{
	add_events( Gdk::BUTTON_PRESS_MASK );
	set_size_request((16*20)+(2*2),(16*20)+(2*2));
	signal_expose_event().connect( sigc::mem_fun(*this, &Palette_Renderer::on_draw));
	signal_button_press_event().connect( sigc::mem_fun(*this,&Palette_Renderer::on_click));
}
Palette_Renderer& Palette_Renderer::operator = ( Palette* nPal )
{
	Reference<Palette>::operator=(nPal);
	on_draw(NULL);
	return *this;
}